Socket
Socket
Sign inDemoInstall

ast-types

Package Overview
Dependencies
1
Maintainers
1
Versions
172
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

    ast-types

Esprima-compatible implementation of the Mozilla JS Parser API


Version published
Maintainers
1
Install size
443 kB
Created

Package description

What is ast-types?

The ast-types npm package is designed to define and manipulate ASTs (Abstract Syntax Trees) efficiently. It provides a flexible way to inspect, transform, and generate code from ASTs, which is particularly useful in the context of building compilers, code analysis tools, and code transformers.

What are ast-types's main functionalities?

Defining AST node types

This feature allows users to define various types of AST nodes. The code sample shows how to define an 'Identifier' and a 'BinaryExpression' node, specifying their structure and inheritance.

const def = require('ast-types').Type.def;
def('Identifier')
  .bases('Node')
  .build('name');
def('BinaryExpression')
  .bases('Expression')
  .build('operator', 'left', 'right');

Building AST nodes

This feature enables the construction of AST nodes using predefined builders. The code sample demonstrates creating a binary expression that adds two literals.

const builders = require('ast-types').builders;
const b = builders;
const ast = b.binaryExpression('+', b.literal(1), b.literal(2));

Visiting AST nodes

This feature provides a mechanism to traverse and manipulate nodes in an AST. The code sample illustrates how to visit all identifier nodes in an AST and log their names.

const visit = require('ast-types').visit;
const ast = require('./some-ast');
visit(ast, {
  visitIdentifier(path) {
    console.log('Found an identifier:', path.node.name);
    this.traverse(path);
  }
});

Other packages similar to ast-types

Readme

Source

AST Types

This module provides an efficient, modular, Esprima-compatible implementation of the abstract syntax tree type hierarchy pioneered by the Mozilla Parser API.

Build Status

Installation

From NPM:

npm install ast-types

From GitHub:

cd path/to/node_modules
git clone git://github.com/benjamn/ast-types.git
cd ast-types
npm install .

Basic Usage

var assert = require("assert");
var n = require("ast-types").namedTypes;
var b = require("ast-types").builders;

var fooId = b.identifier("foo");
var ifFoo = b.ifStatement(fooId, b.blockStatement([
    b.expressionStatement(b.callExpression(fooId, []))
]));

assert.ok(n.IfStatement.check(ifFoo));
assert.ok(n.Statement.check(ifFoo));
assert.ok(n.Node.check(ifFoo));

assert.ok(n.BlockStatement.check(ifFoo.consequent));
assert.strictEqual(
    ifFoo.consequent.body[0].expression.arguments.length,
    0);

assert.strictEqual(ifFoo.test, fooId);
assert.ok(n.Expression.check(ifFoo.test));
assert.ok(n.Identifier.check(ifFoo.test));
assert.ok(!n.Statement.check(ifFoo.test));

AST Traversal

Because it understands the AST type system so thoroughly, this library is able to provide excellent node iteration and traversal mechanisms.

Here's how you might iterate over the fields of an arbitrary AST node:

var copy = {};
require("ast-types").eachField(node, function(name, value) {
    // Note that undefined fields will be visited too, according to
    // the rules associated with node.type, and default field values
    // will be substituted if appropriate.
    copy[name] = value;
})

If you want to perform a depth-first traversal of the entire AST, that's also easy:

var types = require("ast-types");
var Literal = types.namedTypes.Literal;
var isString = types.builtInTypes.string;
var stringCounts = {};

// Count the occurrences of all the string literals in this AST.
require("ast-types").traverse(ast, function(node) {
    if (Literal.check(node) && isString.check(node.value)) {
        if (stringCounts.hasOwnProperty(node.value)) {
            stringCounts[node.value] += 1;
        } else {
            stringCounts[node.value] = 1;
        }
    }
});

Here's an slightly deeper example demonstrating how to ignore certain subtrees and inspect the node's ancestors:

var types = require("ast-types");
var namedTypes = types.namedTypes;
var isString = types.builtInTypes.string;
var thisProperties = {};

// Populate thisProperties with every property name accessed via
// this.name or this["name"] in the current scope.
types.traverse(ast, function(node) {
    // Don't descend into new function scopes.
    if (namedTypes.FunctionExpression.check(node) ||
        namedTypes.FunctionDeclaration.check(node)) {
        // Return false to stop traversing this subtree without aborting
        // the entire traversal.
        return false;
    }

    // If node is a ThisExpression that happens to be the .object of a
    // MemberExpression, then we're interested in the .property of the
    // MemberExpression. We could have inverted this test to find
    // MemberExpressions whose .object is a ThisExpression, but I wanted
    // to demonstrate the use of this.parent.
    if (namedTypes.ThisExpression.check(node) &&
        namedTypes.MemberExpression.check(this.parent.node) &&
        this.parent.node.object === node) {

        var property = this.parent.node.property;

        if (namedTypes.Identifier.check(property)) {
            // The this.name case.
            thisProperties[property.name] = true;

        } else if (namedTypes.Literal.check(property) &&
                   isString.check(property.value)) {
            // The this["name"] case.
            thisProperties[property.value] = true;
        }
    }
});

Within the callback function, this is always an instance of a simple Path type that has immutable .node, .parent, and .scope properties. In general, this.node refers to the same node as the node parameter, this.parent.node refers to the nearest Node ancestor, this.parent.parent.node to the grandparent, and so on. These Path objects are created during the traversal without modifying the AST nodes themselves, so it's not a problem if the same node appears more than once in the AST, because it will be visited with a distict Path each time it appears.

Scope

The object exposed as this.scope during AST traversals provides information about variable and function declarations in the scope that contains this.node. See scope.js for its public interface, which currently includes .isGlobal, .getGlobalScope(), .depth, .declares(name), .lookup(name), and .getBindings().

Custom AST Node Types

The ast-types module was designed to be extended. To that end, it provides a readable, declarative syntax for specifying new AST node types, based primarily upon the require("ast-types").Type.def function:

var types = require("ast-types");
var def = types.Type.def;
var string = types.builtInTypes.string;
var b = types.builders;

// Suppose you need a named File type to wrap your Programs.
def("File")
    .bases("Node")
    .build("name", "program")
    .field("name", string)
    .field("program", def("Program"));

// Prevent further modifications to the File type (and any other
// types newly introduced by def(...)).
types.finalize();

// The b.file builder function is now available. It expects two
// arguments, as named by .build("name", "program") above.
var main = b.file("main.js", b.program([
    // Pointless program contents included for extra color.
    b.functionDeclaration(b.identifier("succ"), [
        b.identifier("x")
    ], b.blockStatement([
        b.returnStatement(
            b.binaryExpression(
                "+", b.identifier("x"), b.literal(1)
            )
        )
    ]))
]));

assert.strictEqual(main.name, "main.js");
assert.strictEqual(main.program.body[0].params[0].name, "x");
// etc.

// If you pass the wrong type of arguments, or fail to pass enough
// arguments, an AssertionError will be thrown.

b.file(b.blockStatement([]));
// ==> AssertionError: {"body":[],"type":"BlockStatement","loc":null} does not match type string

b.file("lib/types.js", b.thisExpression());
// ==> AssertionError: {"type":"ThisExpression","loc":null} does not match type Program

The def syntax is used to define all the default AST node types found in core.js, es6.js, mozilla.js, e4x.js, and fb-harmony.js, so you have no shortage of examples to learn from.

Keywords

FAQs

Last updated on 07 Jul 2014

Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc